package com.dayu.tcp.service.status;

import com.dayu.tcp.listener.EventBehavior;
import com.dayu.tcp.listener.MessageEventListener;
import com.dayu.tcp.logging.Log;
import com.dayu.tcp.logging.LogFactory;
import com.dayu.tcp.service.WrappedChannel;
import com.dayu.tcp.service.server.Server;
import com.dayu.tcp.service.server.ServerContext;
import io.netty.channel.ChannelHandlerContext;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

public class StatusMessageEventListener implements MessageEventListener {

    private static final Log log = LogFactory.getLog(StatusMessageEventListener.class);

    private static final String CMD_STATUS = "get status";

    private static final String CMD_CONFIG = "get config";

    private static final String CMD_QUIT = "quit";

    private static final String CMD_EXIT = "exit";

    private static final String LINE_SEPARATOR = System.lineSeparator();

    @Override
    public EventBehavior channelRead(ChannelHandlerContext ctx, WrappedChannel channel, Object msg) {
        if (msg instanceof String) {
            log.info("status server receive message: " + msg);
            String cmd = (String) msg;
            Map<String, Object> retMap;
            if (CMD_STATUS.equalsIgnoreCase(cmd)) {
                retMap = doGetStatus();
            } else if (CMD_CONFIG.equalsIgnoreCase(cmd)) {
                retMap = doGetConfig();
            } else if (CMD_QUIT.equalsIgnoreCase(cmd) || CMD_EXIT.equalsIgnoreCase(cmd)) {
                channel.close();
                return EventBehavior.BREAK;
            } else {
                retMap = new LinkedHashMap<>();
                retMap.put("error", "unsupported command: " + cmd);
            }
            channel.writeAndFlush(formatResultMap(retMap), false);
        }
        return EventBehavior.CONTINUE;
    }

    /**
     * 获取服务端的统计信息
     *
     * @return
     */
    private Map<String, Object> doGetStatus() {
        Map<String, Object> retMap = new LinkedHashMap<>();
        Server server = ServerContext.getServerContext().getServer();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (server != null) {
            //server名称
            retMap.put("serviceName", server.getServiceName());
            //server启动时间
            retMap.put("serverStartTime", sdf.format(new Date(server.getStartTime())));
            //当前连接数
            retMap.put("clientNumber", server.getCountInfo().getCurrChannelNum().get());
            //最大连接数
            retMap.put("maxClientNumber", server.getCountInfo().getMaxChannelNum().get());
            //最后一次接收消息的时间
            if (server.getCountInfo().getLastReceive().get() > 0) {
                retMap.put("lastReceiveTime", sdf.format(server.getCountInfo().getLastReceive().get()));
            } else {
                retMap.put("lastReceiveTime", "no message received");
            }
            //最后一次发送消息的时间
            if (server.getCountInfo().getLastSend().get() > 0) {
                retMap.put("lastSendTime", sdf.format(server.getCountInfo().getLastSend().get()));
            } else {
                retMap.put("lastSendTime", "no message send");
            }
            //接收消息总数
            retMap.put("receiveNumber", server.getCountInfo().getReceiveNum().get());
            //发送消息总数
            retMap.put("sendNumber", server.getCountInfo().getSendNum().get());
            //接收心跳次数
            retMap.put("heartbeatNumber", server.getCountInfo().getHeartbeatNum().get());
        } else {
            retMap.put("error", "server is not available!");
        }
        return retMap;
    }

    /**
     * 获取服务端的配置信息
     *
     * @return
     */
    private Map<String, Object> doGetConfig() {
        Map<String, Object> retMap = new LinkedHashMap<>();
        Server server = ServerContext.getServerContext().getServer();
        if (server != null) {
            retMap.put("ip", server.getIp() == null ? "no ip" : server.getIp());
            retMap.put("port", server.getPort());
            retMap.put("keepAlive", server.isKeepAlive());
            retMap.put("tcpNoDelay", server.isTcpNoDelay());
            retMap.put("openExecutor", server.isOpenExecutor());
            if (server.isOpenExecutor()) {
                retMap.put("corePoolSize", server.getCorePoolSize());
                retMap.put("maximumPoolSize", server.getMaximumPoolSize());
                retMap.put("queueCapacity", server.getQueueCapacity());
            }
        } else {
            retMap.put("error", "server is not available!");
        }
        return retMap;
    }

    /**
     * 发送消息给调用者
     *
     * @return
     */
    private Object formatResultMap(Map<String, Object> retMap) {
        if (retMap == null || retMap.isEmpty()) {
            return "糟糕,什么都没有!!!";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("{").append(LINE_SEPARATOR);
        for (Map.Entry<String, Object> entry : retMap.entrySet()) {
            sb.append(String.format(" %-25s", entry.getKey())).append(":\t").append(entry.getValue()).append(LINE_SEPARATOR);
        }
        sb.append("}").append(LINE_SEPARATOR);
        return sb.toString();
    }
}
